package server;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;
import lagern.*;
import lagern.LagerPackage.exAlreadyExists;
import lagern.LagerPackage.exNotFound;

/**
 * Implementation of the interface LagerPOA
 * @author Laurine and Vincent
 *
 */
public class LagerImpl extends LagerPOA {
	
	//to store the Facher created
	private static Map<String, FachImpl> listFacher = new HashMap<String, FachImpl>();
	//to store the Monitor which are registered
	private static ArrayList<Monitor> listMonitor = new ArrayList<Monitor>();
	private POA rootPOA;
	
	public LagerImpl(POA rootPOA)
	{
		this.rootPOA = rootPOA;
	}

	/**
	 * Creates a new storage location
	 */
	@Override
	public Fach neu(String user, String name) throws exAlreadyExists {
		if(listFacher.containsKey(name))
		{
			throw new exAlreadyExists("A compartment with the name " + name + " already exists");
		}
		else
		{
			//creation of the new Fach
			FachImpl newFach = new FachImpl(name,this);
			//save in the list
			listFacher.put(name, newFach);
			try{
				rootPOA.activate_object(newFach);
				displayOnMonitors(user,"Fach with the name " + name + " was created");
				return FachHelper.narrow(rootPOA.servant_to_reference(
	                    newFach));
			}catch (Exception e)
			{
				System.err.println("Error occured during the creation process");
			}
		}
		
		return null;
	}

	/**
	 * @return a storage location from the name
	 */
	@Override
	public Fach hole(String user, String name) throws exNotFound {
		if(!listFacher.containsKey(name))
		{
			throw new exNotFound("The Fach " + name + " doesn't exist");
		}
		else
		{
			try {
				return FachHelper.narrow(rootPOA.servant_to_reference(listFacher.get(name)));
			} catch (Exception e) {
				System.err.println("Fach " + name + " couldn't be find");
			}
		}
		return null;
	}

	/**
	 * @return a list of all the storage locations.
	 */
	@Override
	public Fach[] holeLagerListe() {
		Fach[] toReturn=new Fach[1000];
		int i=-1;
		for(FachImpl fach : listFacher.values())
		{
			i++;
			try {
				toReturn[i]=FachHelper.narrow(rootPOA.servant_to_reference(fach));
			} catch (Exception e){
				System.err.println("Problem when building the list");
			}
		}
		return toReturn;
	}

	/**
	 * activates the Monitor
	 */
	@Override
	public void aktiviereMonitor(Monitor theMonitor) {
		listMonitor.add(theMonitor);	
	}

	/**
	 * stops the Monitor
	 */
	@Override
	public void entferneMonitor(Monitor theMonitor) {
		listMonitor.remove(theMonitor);
		
	}

	/**
	 * to quit	
	 */
	@Override
	public void quit() {
		for(Monitor monitor: listMonitor)
			monitor.quit();
		System.out.println("Shutdown of the server..");
		final ORB orb = super._orb();
		new Thread() {
			public synchronized void run(){
				orb.shutdown(true);
			}
		}.start();
	}
	
	/**
	 * To display messages on the monitor(s)
	 * @param user the message comes from
	 * @param message to log
	 */
	public void displayOnMonitors(String user, String message) {
		for(Monitor monitor: listMonitor)
			monitor.aktion(user, message);
		
	}

}
